package com.ruoyi.common.utils;

import com.auth0.jwt.JWT;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTVerificationException;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.auth0.jwt.interfaces.JWTVerifier;
import org.apache.shiro.cache.Cache;
import org.apache.shiro.cache.CacheManager;

import java.util.Date;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * JWT Token工具类，用于生成和验证登录Token
 */
public class JwtShortTokenUtil {
    // 密钥，实际应用中应从配置文件获取并确保安全
    private static final String SECRET_KEY = "GanSuHuaYue8487111";

    /**
     * 生成JWT Token (保持最小化，仅包含用户ID和过期时间)
     *
     * @param userId         用户唯一标识
     * @param expirationTime 过期时间（毫秒）
     * @return 生成的JWT Token字符串
     */
    public static String generateToken(final String userId, final long expirationTime) {
        Algorithm algorithm = Algorithm.HMAC256(SECRET_KEY);

        // 仅添加必要的用户ID和过期时间，最大限度减小Token体积
        return JWT.create()
                .withClaim("userId", userId)
                .withExpiresAt(new Date(System.currentTimeMillis() + expirationTime))
                .sign(algorithm);
    }

    /**
     * 验证Token并返回用户ID
     *
     * @param token 待验证的Token
     * @return 验证成功返回用户ID，失败返回null
     */
    public static String verifyToken(String token) {
        // 检查Token是否为空
        if (StringUtils.isEmpty(token)) {
            return null;
        }
        try {
            // 验证Token并解析用户ID
            Algorithm algorithm = Algorithm.HMAC256(SECRET_KEY);
            JWTVerifier verifier = JWT.require(algorithm).build();
            DecodedJWT jwt = verifier.verify(token);
            return jwt.getClaim("userId").asString();
        } catch (JWTVerificationException e) {
            // Token验证失败（无效、过期等）
            return null;
        }
    }

    /**
     * 检查Token是否过期
     *
     * @param token 待检查的Token
     * @return true表示已过期，false表示未过期
     */
    public static boolean isTokenExpired(String token) {
        try {
            DecodedJWT jwt = JWT.decode(token);
            return jwt.getExpiresAt().before(new Date());
        } catch (JWTVerificationException e) {
            return true; // 无效Token视为已过期
        }
    }


    // 添加main方法用于测试
    public static void main(String[] args) {
        // 测试参数
        String testSubject = "admin"; // 测试用的用户标识


        System.out.println("\n--------------- 给定Token验证演示 ---------------");
        String generatedToken = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOiJvaG03djRuSUlvR2hubGtYaHJxNWhpSzNwcV82IiwiZXhwIjoxNzYxMjAyNjI3fQ.hlp-7AUAyt3es4Q5pwTcWDhoUW8alw6QpuT4C4s-SJU";
        try {
            String validatedSubject = verifyToken(generatedToken);
            System.out.println("有效Token验证结果: " + validatedSubject);
            if (testSubject.equals(validatedSubject)) {
                System.out.println("✅ 基础Token验证成功");
            } else {
                System.out.println("❌ 基础Token验证失败");
            }
        } catch (Exception e) {
            System.out.println("❌ 基础Token验证抛出异常: " + e.getMessage());
        }


        // 1.基础Token演示
        System.out.println("\n--------------- 基础Token演示 ---------------");
        // 1.1 生成基础Token
        generatedToken = generateToken(testSubject, 10 * 60 * 1000);
        System.out.println("成功生成Token: " + generatedToken);

        // 1.2 基础Token验证
        try {
            String validatedSubject = verifyToken(generatedToken);
            System.out.println("有效Token验证结果: " + validatedSubject);
            if (testSubject.equals(validatedSubject)) {
                System.out.println("✅ 基础Token验证成功");
            } else {
                System.out.println("❌ 基础Token验证失败");
            }
        } catch (Exception e) {
            System.out.println("❌ 基础Token验证抛出异常: " + e.getMessage());
        }

        // 2.无效Token验证演示
        System.out.println("\n--------------- 无效Token验证演示 ---------------");
        // 2.1 生成待验证的Token
        generatedToken = generateToken(testSubject, 10 * 60 * 1000);
        System.out.println("成功生成Token: " + generatedToken);
        // 2.2 测试无效Token验证（篡改Token）
//        String invalidToken = generatedToken + "tam";
        String invalidToken = generatedToken.substring(0, generatedToken.length() - 3);
        try {
            String invalidSubject = verifyToken(invalidToken);
            System.out.println("❌ 无效Token验证异常: " + invalidSubject);
        } catch (Exception e) {
            System.out.println("✅ 无效Token验证失败（预期结果）: " + e.getMessage());
        }


        // 4. 测试过期Token验证（如果需要可添加，这里假设设置极短有效期后等待过期）
        System.out.println("\n--------------- 过期Token验证演示 ---------------");
        // 4.1 生成过期Token
        long expirationTime = 2000; // 2秒有效期
        String shortExpireToken = generateToken(testSubject, expirationTime);
        System.out.println("成功生成过期Token: " + shortExpireToken);
        // 4.2 测试过期Token验证
        try {
            Thread.sleep(expirationTime); // 等待2秒使其过期
            String validatedSubject = verifyToken(shortExpireToken);
            if (validatedSubject == null) {
                System.out.println("❌ 过期Token验证异常，不通过");
            } else {
                System.out.println("✅ 过期Token验证成功");
            }
        } catch (Exception e) {
            System.out.println("❌ 过期Token验证失败（预期结果）: " + e.getMessage());
        }
    }
}